#!/usr/bin/env perl
# A program to process Quran translation zip file for Zekr project into the one for Drupal Quran module
# License: GNU GPL 2
# Author: Muhammad Ichsan <ichsan@gmail.com>
# Finished on: Sept 25, 2008
# Requirement:
# 1. Perl with File module
# 2. Command: unzip, bzip2, iconv

use File::Find;
use File::Path;

if ($#ARGV < 1) {
  print "Usage: ./proc-quran <country code> <db type 1> <db type 2> ... e.g. ./proc-quran en pgsql mysql \n";
  exit 0;
}

$lang = $ARGV[0];
@db_types = @ARGV[1..$#ARGV];

$base_dir = "/tmp/quranlab";
$working_dir = "$base_dir/$lang";
$insertfile = "$working_dir/sql-tmp.txt";

print "Processing Quran for lang = $lang\n";

# Preparation
mkdir($base_dir, 0700);
rmtree($working_dir);
mkdir($working_dir, 0700) or die ("Can not create directory $working_dir");

system("unzip -qod $working_dir \"zip-sources/$lang.zip\"");

$textfile = "notfound.txt";
find(\&wanted, $working_dir);
sub wanted {
  $textfile = "$File::Find::dir/$_" if /txt$/i;
}
find(\&wanted2, $working_dir);
sub wanted2 {
  $infofile = "$File::Find::dir/$_" if /properties$/i;
}

$encoding = get_info("encoding", $infofile);
$textfile = to_utf8($textfile, $encoding);
$infofile = to_utf8($infofile, $encoding);

$translator = get_info("name", $infofile);
$copyright = get_info("copyright", $infofile);

# Creating data for chapters
print "Creating sura data...\n";
print_csv_insert($lang, $insertfile) or die "Process can not continue\n";

print "Creating aya data...\n";
write_verses($lang, $textfile, $insertfile) or  die "Process can not continue\n";
print "\n";

foreach $db_type (@db_types) {
  print "Processing for db = $db_type\n";
  require "./lib/$db_type.pl";

  # Prepare insert table
  $sqlfile = "$working_dir/$db_type.sql.tmp";

  unlink($sqlfile);
  prepare_tables($lang, $translator, $copyright, $sqlfile);

  # Append to sqlfile
  open(SQL_FILE, ">>$sqlfile");
  open(SQL_TMP, $insertfile);
  while (<SQL_TMP>) { print SQL_FILE $_; }
  close(SQL_TMP);
  close(SQL_FILE);

  print "Importing...\n";
  import_tables($lang, $sqlfile);

  print "Exporting...\n";
  export_tables($lang);
}

print "Process has finished\n";


############# Functions
sub sql_sanitize {
  my $text = shift;
  $text =~ s/'/\\'/g; # "Saa'd" => "Saa\'d"

  # Trimming " Game" => "Game"
  $text =~ s/^\s+//;
  $text =~ s/\s+$//;

  $text =~ s/$//; # removing DOS line ending

  return $text;
}

# Write sql for verses into a file
sub write_verses {
  local($lang, $textfile, $outfile, $num_of_aya_list, $line, $success, $id, $i,
    $num_of_aya, $sura, $aya, $last_line);

  $lang = shift;
  $textfile = shift;
  $outfile = shift;

  @num_of_aya_list = (7, 286, 200, 176, 120, 165, 206, 75, 129, 109, 123, 111, 43,
    52, 99, 128, 111, 110, 98, 135, 112, 78, 118, 64, 77, 227, 93, 88, 69, 60, 34,
    30, 73, 54, 45, 83, 182, 88, 75, 85, 54, 53, 89, 59, 37, 35, 38, 29, 18, 45,
    60, 49, 62, 55, 78, 96, 29, 22, 24, 13, 14, 11, 11, 18, 12, 12, 30, 52, 52,
    44, 28, 28, 20, 56, 40, 31, 50, 40, 46, 42, 29, 19, 36, 25, 22, 17, 19, 26,
    30, 20, 15, 21, 11, 8, 8, 19, 5, 8, 8, 11, 11, 8, 3, 9, 5, 4, 7, 3, 6, 3, 5,
    4, 5, 6 );

  open(AYA, $textfile);
  open(SQL_TMP, ">>$outfile");
  $success = 1;

  $line = "";
  $id = 0;
  print "Processing sura: ";

  for ($i = 0; $i <= $#num_of_aya_list; $i++) {
    $num_of_aya = $num_of_aya_list[$i];
    $sura = $i + 1;
    print "$sura ";

    for ($j = 0; $j < $num_of_aya; $j++) {
      $id ++;
      $aya = $j + 1;

      if ($line = <AYA>) {
        $line = sql_sanitize($line);
        print SQL_TMP "INSERT INTO quran_verses_$lang VALUES ('$id', $sura, $aya, '$line');\n";
      } else {
        print "\nMissing line $id for Sura $sura Aya $aya\n";
        $success = 0;
        last 2;
      }
    }
  }

  close(SQL_TMP);
  close(AYA);

  # Check if the last line is the real end of file
  $last_line = sql_sanitize(last_line($textfile));

  if (!($last_line eq $line)) {
    print "\n$textfile was improperly created. The last line should be the last aya\n";
    $success = 0;
  }

  return $success;
}

# Clear BOM on a file
sub clearbom_onfile {
  my $infile = shift;
  my $outfile = shift;

  open(INFILE, $infile);
  my @file = <INFILE>;
  $file[0] =~ s/^\xEF\xBB\xBF//;
  close(INFILE);

  open(OUTFILE, ">$outfile");
  print OUTFILE @file;
  close(OUTFILE);

  return 1;
}


sub print_csv_insert {
  local($lang, $file, $outfile, $line, $number, $i, $success);

  $lang = shift;
  $outfile = shift;

  $success = 1;
  $file = "chapters-csv/$lang.csv";
  $file = "chapters-csv/en.csv" unless (-r $file);

  open(SQL_TMP, ">>$outfile");
  open(CSVFILE, $file);
  for ($i = 1; $i <= 114; $i++) {
    if ($line = <CSVFILE>) {
      $line =~ s/"//g;
      @exploded = split(';', $line);

      $arabic = sql_sanitize($exploded[0]);
      $translation = sql_sanitize($exploded[1]);

      print SQL_TMP "INSERT INTO quran_chapters_$lang VALUES ($i, '$arabic', '$translation');\n";

    } else {
      print "Missing line $i\n";
      $success = 0;
      last;

    }
  }
  close(CSVFILE);
  close(SQL_TMP);

  return $success;
}

sub to_utf8 {
  my $file = shift;
  my $encoding = shift;

  $result = system("iconv -f $encoding -t utf8 $file 2>&1 > \"$file.utf8\"");
  if ("$result" eq "0") {
    $file = "$file.utf8";
  }

  return $file;
}

sub get_info {
  local($field, $infofile, $line, $value);
  $field = shift;
  $infofile = shift;
  $value = "";
  
  open(INFO_FILE, $infofile);
  while (($line = <INFO_FILE>) && ($value eq "")) {
    if ($line =~ /$field=/) {
      $value = $line;
      $value =~ s/$field=//;
      $value = sql_sanitize($value);
    }
  }
  close(INFO_FILE);

  return $value;
}

sub last_line {
  local(@lines, $file);
  $file = shift;

  open(FILE, $file);
  @lines = <FILE>;
  close(FILE);

  return $lines[$#lines];
}
